package com.realdolmen.whiteyellowcross.servlet;

import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.realdolmen.whiteyellowcross.appengine.datastore.PersonelAppEngineDataStore;
import com.realdolmen.whiteyellowcross.appengine.datastore.WaitWorkShiftAppEngineDataStore;
import com.realdolmen.whiteyellowcross.appengine.datastore.WaitWorkShiftDayPlanAppEngineDataStore;
import com.realdolmen.whiteyellowcross.datastore.PersonelDataStore;
import com.realdolmen.whiteyellowcross.datastore.WaitWorkShiftDataStore;
import com.realdolmen.whiteyellowcross.datastore.WaitWorkShiftDayPlanDataStore;
import com.realdolmen.whiteyellowcross.model.Personel;
import com.realdolmen.whiteyellowcross.model.WaitMonthPlanning;
import com.realdolmen.whiteyellowcross.model.WaitWorkShiftDayPlan;
import com.realdolmen.whiteyellowcross.service.*;

@SuppressWarnings("serial")
public class WaitCalendarServlet extends HttpServlet {

    //private static final String NO_REFRESH = "NOT_EXISTS";
    private static final String LOAD_WAIT_CALENDAR_ACTION_REQUEST_PARAM_VALUE = "loadWaitCalendar";
    private static final String UPDATE_WAIT_CALENDAR_ACTION_REQUEST_PARAM_VALUE = "updateWaitCalendar";

    private static final String CALENDAR_ACTION_REQUEST_PARAM = "action";
    private static final String WAIT_WORKSHIFT_DAY_PLAN_ID_REQUEST_PARAM = "waitWorkShiftDayPlanId";
    private static final String PERSONEL_ID_REQUEST_PARAM = "personelId";
    private static final String CALENDAR_YEAR_REQUEST_PARAM = "year";
    private static final String CALENDAR_MONTH_REQUEST_PARAM = "month";




    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        StringBuffer resultingHtml = new StringBuffer();

        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        WaitWorkShiftDayPlanDataStore waitWorkShiftDayPlanDataStore = WaitWorkShiftDayPlanAppEngineDataStore.getInstance(ds);
        PlanningService planningService = PlanningPersistenceBasedService.getInstance(waitWorkShiftDayPlanDataStore);
        PersonelDataStore personelDataStore = PersonelAppEngineDataStore.getInstance(ds);
        PersonelService personelService = PersonelPersistenceBasedService.getInstance(personelDataStore);
        WaitWorkShiftDataStore waitWorkShiftDataStore = WaitWorkShiftAppEngineDataStore.getInstance(ds);
        WaitWorkShiftService waitWorkShiftService = WaitWorkShiftPersistenceBasedService.getInstance(waitWorkShiftDataStore);

        String action = req.getParameter(CALENDAR_ACTION_REQUEST_PARAM);

        if (action.equals(LOAD_WAIT_CALENDAR_ACTION_REQUEST_PARAM_VALUE)) {
            performLoadWaitCalendar(resultingHtml, req, planningService, personelService, waitWorkShiftService);
        } else if (action.equals(UPDATE_WAIT_CALENDAR_ACTION_REQUEST_PARAM_VALUE)) {
            performUpdateCalendar(req, planningService);
            performLoadWaitCalendar(resultingHtml, req, planningService, personelService, waitWorkShiftService);
        }
        try {
            if (resultingHtml != null && resultingHtml.toString().length() > 0) {
                resp.getWriter().print(resultingHtml.toString());
                resp.getWriter().flush();
            }
        } catch (IOException ioe) {

        }

    }

    private void generateWaitCalendarHeader(StringBuffer resultingHtml) {
        resultingHtml.append("<table id=\"calendar_table_header\">\n");
        resultingHtml.append("\t<thead>\n");
        resultingHtml.append("\t\t<tr>\n");
        resultingHtml.append("\t\t\t<th class=\"table_header_links\" onclick=\"previousYear();\">Vorige maand</th>\n");
        resultingHtml.append("\t\t\t<th class=\"table_header_links\" onclick=\"previousMonth();\">Vorig jaar</th>\n");
        resultingHtml.append("\t\t\t<th>Wachtkalendar</th>\n");
        resultingHtml.append("\t\t\t<th class=\"table_header_links\" onclick=\"nextMonth();\">Volgende maand</th>\n");
        resultingHtml.append("\t\t\t<th class=\"table_header_links\" onclick=\"nextYear();\">Volgend jaar</th>\n");
        resultingHtml.append("\t\t</tr>\n");
        resultingHtml.append("\t</thead>\n");
        resultingHtml.append("</table>\n");
    }

    private void generateWorkShiftPlan(Personel[] personelList, WaitWorkShiftDayPlan morningWorkShiftPlan, WaitMonthPlanning waitMonthPlanning, StringBuffer resultingHtml) {


        resultingHtml.append("\t<td>");
        resultingHtml.append("\t<select>");

        generatePersonelList(personelList, morningWorkShiftPlan.getPersonel().getName(), resultingHtml);
        resultingHtml.append("\t</select>");
        resultingHtml.append("</td>");
    }


    private void generatePersonelList(Personel[] personelList, String personelName, StringBuffer resultingHtml) {
        for (Personel personel : personelList) {
            if (personelName.equalsIgnoreCase(personel.getName())) {
                resultingHtml.append("\t<option selected>" + personel.getName());
            } else {
                resultingHtml.append("\t<option>" + personel.getName());
            }
            resultingHtml.append("\t</option>");
        }
    }

    private WaitMonthPlanning getWaitMonthPlanning(HttpServletRequest request, PlanningService planningService, PersonelService personelService, WaitWorkShiftService waitWorkShiftService) {
        String year = request.getParameter(CALENDAR_YEAR_REQUEST_PARAM);
        String month = request.getParameter(CALENDAR_MONTH_REQUEST_PARAM);

        if (year == null && year.length() == 0 && month == null && month.length() == 0) {
            year = new Integer(Calendar.getInstance().get(Calendar.YEAR)).toString();
            month = new Integer(Calendar.getInstance().get(Calendar.MONTH) + 1).toString();
        }
        WaitMonthPlanning waitMonthPlanning = planningService.getWaitMonthPlanning(new Integer(year).intValue(), new Integer(month).intValue(), personelService.getPersonelList(), waitWorkShiftService.getWorkShiftList(), true);
        return waitMonthPlanning;
    }

    private void performLoadWaitCalendar(StringBuffer resultingHtml,
                                         HttpServletRequest request, PlanningService planningService, PersonelService personelService, WaitWorkShiftService waitWorkShiftService) {
        WaitMonthPlanning waitMonthPlanning = getWaitMonthPlanning(request, planningService, personelService, waitWorkShiftService);
        generateWaitCalendarHeader(resultingHtml);
        generateWaitCalendarBody(resultingHtml, waitMonthPlanning, personelService);
        generateWaitCalendarFooter(resultingHtml, waitMonthPlanning);
    }


    private void generateWaitCalendarBody(StringBuffer resultingHtml, WaitMonthPlanning waitMonthPlanning, PersonelService personelService) {
        Personel[] personelList = (Personel[]) personelService.getPersonelList().toArray(new Personel[personelService.getPersonelList().size()]);
        for (Integer day : waitMonthPlanning.getWaitWorkShiftDayPlannings().keySet()) {
            List<WaitWorkShiftDayPlan> waitWorkShiftPlan = waitMonthPlanning.getWaitWorkShiftDayPlanning(day);
            WaitWorkShiftDayPlan morningWorkShiftPlan = waitWorkShiftPlan.get(0);
            WaitWorkShiftDayPlan afterNoonShiftPlan = waitWorkShiftPlan.get(1);
            WaitWorkShiftDayPlan eveningShiftPlan = waitWorkShiftPlan.get(2);
            resultingHtml.append("<tr>");
            resultingHtml.append("\t<td colspan=\"2\">").append(day + "/" + waitMonthPlanning.getMonth() + "/" + waitMonthPlanning.getYear()).append("</td>");
            generateWorkShiftPlan(personelList, morningWorkShiftPlan, waitMonthPlanning, resultingHtml);
            generateWorkShiftPlan(personelList, afterNoonShiftPlan, waitMonthPlanning, resultingHtml);
            generateWorkShiftPlan(personelList, eveningShiftPlan, waitMonthPlanning, resultingHtml);
            resultingHtml.append("</tr>");
        }
    }


    private void generateWaitCalendarFooter(StringBuffer resultingHtml, WaitMonthPlanning waitMonthPlanning) {
        Map<Personel, Integer> personelMonthTotals = waitMonthPlanning.getPersonelMonthTotals();
        resultingHtml.append("<tr>");
        resultingHtml.append("<th colspan=\"4\"></th>");
        resultingHtml.append("<th>Adrukken</th>");
        resultingHtml.append("</tr>");

        for (Personel personel : personelMonthTotals.keySet()) {
            Integer total = personelMonthTotals.get(personel);
            resultingHtml.append("<tr>");
            resultingHtml.append("<td colspan=\"2\">").append(personel.getName()).append("</td>");
            resultingHtml.append("<td colspan=\"3\">").append(total).append("</td>");
        }
    }

    private void performUpdateCalendar(
            HttpServletRequest request, PlanningService planningService) {
        String waitWorkShiftDayPlanId=request.getParameter(WAIT_WORKSHIFT_DAY_PLAN_ID_REQUEST_PARAM);
        String personelId = request.getParameter(PERSONEL_ID_REQUEST_PARAM);


        planningService.updateWaitMonthPlanning(waitWorkShiftDayPlanId,personelId);


    }
}